


let Vue  // 存储vue


// 申明一个VueRouter 类
class VueRouter {
    constructor(options) {
        this.$options = options
        // 需要响应式一下
        this.current = window.location.hash.slice(1) || '/' // 初始加载获取默认地址
        // vue内部api 可以让绑定属性变为响应式
        // Vue.util.defineReactive(
        //     this,
        //     "current",
        //     window.location.hash.slice(1) || "/"
        // );
        // 响应式数组
        Vue.util.defineReactive(
            this,
            'matched',
            []
        )

        // 判断和收集路由数组
        this.match()

        window.addEventListener('hashchange', () => { // 监听地址改变时获取当前地址
            this.current = window.location.hash.slice(1)
            this.matched = []
            this.match()
        })
    }

    match(routes){
        routes = routes || this.$options.routes
        for(let route of routes) {
            if (route.path === '/' && this.current === '/') {
                this.matched.push(route)
                return 
            }
            if (route.path !== '/' && this.current.includes(route.path)) {
                this.matched.push(route)
                route.children && this.match(route.children)
                return
            }
        }
    }
}



//创建一个install方法
VueRouter.install = function (_Vue) {
    Vue = _Vue

    // 全局混入一个 beforeCreat
    Vue.mixin({
        beforeCreate() {
            // 仅在根组件创建时执行一次
            if (this.$options.router) {
                Vue.prototype.$router = this.$options.router;
            }
        },
    })

    // 注册 router-link 和 router-view
    Vue.component('router-view', {
        render(h) {
            // routerView 标识
            this.$vnode.data.routerView = true
            let depth = 0
            let parent = this.$parent
            while (parent) {
                const vnodeData = parent.$vnode && parent.$vnode.data
                if(vnodeData) {
                    if(vnodeData.routerView) {
                        depth++
                    }   
                }
                parent = parent.$parent  
            }
            // 获取对应组件
            let component = null
            // // 获取地址和配置项
            // const { current, $options } = this.$router
            // // 匹配对应路径的组件
            // const router = $options.routes.find(val => {
            //     return val.path === current
            // })
            const router = this.$router.matched[depth]
            // 如果匹配成功获取组件
            router && (component = router.component)
            return h(component)
        }   
    })

    Vue.component('router-link', {
        props: {
            to: {
                type: String,
                required: true
            }
        },
        render(h) {
            // <router-link to="/about">xxx</router-link>
            // <a href="#/about">xxx</a>
            // 加'#'变成哈希
            return h('a', { attrs: { href: '#' + this.to } }, this.$slots.default)
        }
    })
}



export default VueRouter;